﻿using System.Collections.Generic;
using BitBenderGames;
using Unity.Mathematics;
using UnityEngine;
using WorldMap.TouchCamera;
using WorldMapBase;
using WorldMapBase.Camera;
using WorldMapBase.Collision;
using WorldMapBase.Display;
using WorldMapBase.Layer;
using WorldMapBase.LOD;
using WorldMapBase.Tile;
using WorldMapBase.Tile.Pool;
using WorldMapNew;
using XLua;
using Yoozoo.Managers;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

public enum LODLevelEnum
{
    Unknow = -1,

    LOD0,
    LOD1,
    LOD2,
    LOD3,
    LOD4,
    LOD5,
    LODLevelCount,
};
public class WorldEntry
{
    public enum ConstResId {
        cloud = 102,
        mapUnion = 2,
        mapPoint = 1,
    };
    public static WorldEntry instance;
    public static bool UpdateSwitch = false;
    // 默认LOD策略高度
    // 16 到 130 为lod0的树并且具有缩放
    // 大于 310 切换 lod1
    // 大于 530 切换 lod2
    public static float DISTANCE_LOD0 = 6.5f;    
    public static float DISTANCE_LOD1 = 8f;  
    // lod1隐藏沙盘的装饰物   
    public static float DISTANCE_LOD2 = 11f;
    // 出现缩略图标
    public static float DISTANCE_LOD3 = 25f;
    // public static float DISTANCE_LOD4 = 25f;
    public static float DISTANCE_LOD4 = 80f;

    // public static float DISTANCE_LOD5 = 150f;
    public static float DISTANCE_LOD5 = 800f;
    // 部队LOD与沙盒LOD的对应关系
    // 部队分5级LOD，LOD1~LOD5，数组中存放的是每一档的最大值，如LOD1的最大值对应沙盒的LOD1 20%
    public static readonly int MarchLodLevelCount = 5;
    public static readonly int[] MarchLodLevels = { 1, 2, 3, 4, 5 };
    public static readonly float[] MarchLodPercents = { 100, 100, 100, 100, 100 };

    //最大显示小兵的lod等级  3一下不显示方阵
    public static int MaxShowMarchLodLevel = 3;
    //树显示阴影的最大等级
    public static int TreeShadowMaxLod = 2;

    /// <summary>
    /// 地块层名称
    /// </summary>
    public const string PLANE_LAYER_NAME = "LayerPlane";
    /// <summary>
    /// 树层名称
    /// </summary>
    public const string TREE_LAYER_NAME = "LayerTree";
    /// <summary>
    /// 山层
    /// </summary>
    public const string MOUNTAIN_LAYER_NAME = "LayerMountain";
    /// <summary>
    /// 山脉层
    /// </summary>
    public const string MOUNTAINRANGE_LAYER_NAME = "LayerMountainRange";
    /// <summary>
    /// 装饰层 // 栏杆、围墙
    /// </summary>
    public const string DECORATION_LAYER_NAME = "LayerDecoration";
    /// <summary>
    /// 交通层 // 红绿灯 小车
    /// </summary>
    public const string TRAFFIC_LAYER_NAME = "LayerTraffic";
    /// <summary>
    /// 出生点层 // 主堡出生点 联盟建筑出生点
    /// </summary>
    public const string MAP_POINT_NAME = "LayerMapPoint";
    /// <summary>
    /// 街区点车道层 // 
    /// </summary>
    public const string ALLIANCEPOINT_ROAD_LAYER_NAME = "LayerAlliancePointRoad";
    /// <summary>
    /// 街区点车道层 // 
    /// </summary>
    public const string ALLIANCEPOINT_CROSS_LAYER_NAME = "LayerAlliancePointCross";
    /// <summary>
    /// 出生点装饰物
    /// </summary>
    public const string MAP_POINT_ADORN_LAYER_NAME = "LayerPointAdorn";

    public const int PLANE_LAYER_ID = 0;
    public const int MOUNTAINRANGE_LAYER_ID = 1;
    public const int TREE_LAYER_ID = 2;
    public const int MOUNTAIN_LAYER_ID = 3;
    public const int DECORATION_LAYER_ID = 4;
    public const int TRAFFIC_LAYER_ID = 5;
    public const int MAP_POINT_ID = 6;

    public const int ALLIANCEPOINT_ROAD_LAYER_ID = 7;
    public const int ALLIANCEPOINT_CROSS_LAYER_ID = 8;

    public const int MAP_POINT_ADORN_LAYER_ID = 9;

    public static float ViewRectScaleRatio = 2f; // 防穿帮的外扩的视图缩放系数

    public float[] m_LODArray;

    public static bool bMapPointShow = false; // 主城出生点显示
    public static bool bMapPointCheck = false; // 
    

    public static int m_iTileSize = 30; // 地图块尺寸 可读取地图数据后更新
    public static int m_mapSize = 1200 + 180; // 地图尺寸 可读取地图数据后更新

    public static int m_mapLandSize = 1200;// 陆地尺寸

    public static int m_overSeaSize = 180;// 海外副本尺寸 

    public static int m_seaSize = 1200 + 180 + 0; // 海岸线尺寸 可读取地图数据后更新 后续还是需要修改

    public static int m_mapDataSize = 1200 + 180 + 60;// 地图数据尺寸
    public static int m_mapDataOffset = 60;// 地图数据中心偏移

    // 用于显示山体的碰撞范围
    private LayerContainerManager m_LayerContainerMananger;
    private LODManager m_LODManager;
    private DisplayCommandManager m_DisplayCommandManager;

    //private CameraLayerContainerStrategy m_CameraLayerContainerStrategy;
    private GridLodCameraLayerContainerStrategy m_CameraLayerContainerStrategy;
    private CameraHeightLODStrategy m_DefaultCameraHeightLODStrategy;

    private ICamera m_Camera;

    private CircleSimpleBoolCollisionData m_TreeLayerCollisionData;

    private TouchCameraController _touchCameraController;


    private TrafficSystem _trafficSystem;

    private WorldGlobalLodListener _worldGlobalLodListener;

    private WorldAudioController _worldAudioController;

    // 
    public MapAlliancePointSystem _alliancePointSystem;
    public MapPointAdornSystem _mapPointAdornSystem;

    public static float resPointOffset = 0.39f;

    public WorldEntry(ICamera camera)
    {
        ClassManager.Store<MultiElementTile>(400);
        ClassManager.Store<DisplayCmdHashContainer>(40);
        var worldCamra = camera.GetCamera();
        _touchCameraController = worldCamra.GetComponent<TouchCameraController>();
        m_Camera = camera;

        m_LODArray = new[]
        {
            DISTANCE_LOD0,
            DISTANCE_LOD1,
            DISTANCE_LOD2,
            DISTANCE_LOD3,
            DISTANCE_LOD4,
            DISTANCE_LOD5,
        };

        _touchCameraController.Init(m_LODArray);
        _worldGlobalLodListener = new WorldGlobalLodListener();

        instance = this;

#if UNITY_EDITOR
        _touchCameraController.onValidate += OnCameraValidate;
#endif
        //_touchCameraController.UpdateZoomDistance(DISTANCE_LOD0,DISTANCE_LOD5);
    }

    public void SetMapPointState(int tileIdx, int posIdx, bool state, bool disAdorn,
        int type = (int)MapPointType.E_CityAndRes, long allianceId = 0,float point_x = 0,float point_y = 0)
    {
        LODTileLayerListener layerListener = TileDisplayManager.Instance.GetTileLayerListener(MAP_POINT_ID);
        if (layerListener != null) layerListener.SetMapPointState(tileIdx, posIdx, state);
        if (type == (int)MapPointType.E_Alliance)
        {
            // 更新街区点道路 -舍弃 现在不使用沙盘建筑数据了
            //_alliancePointSystem.UpdateAlliancePointState(tileIdx, posIdx, !state, allianceId, point_x, point_y);
        }
        else
        {
            // 更新装饰物 只有新增需要更新 
            if (!state)
            {
                int iDisAdorn = disAdorn ? 1 : -1;
                _mapPointAdornSystem.UpdatePointState(tileIdx, tileIdx * 1000 + posIdx, !state, point_x, point_y, iDisAdorn);
            }
        }
    }

    public void ResetAdorn()
    {
        if (_alliancePointSystem) _alliancePointSystem.ResetAdorn();
        if (_mapPointAdornSystem) _mapPointAdornSystem.ResetAdorn();
    }

    public static bool GetMapPointState(int tileIdx, int posIdx)
    {
        LODTileLayerListener layerListener = TileDisplayManager.Instance.GetTileLayerListener(MAP_POINT_ID);
        if (layerListener != null) return layerListener.GetMapPointState(tileIdx, posIdx);
        return true; // 默认显示 等待视野删除
    }

    // 出生点类型
    public enum MapPointType
    {
        E_Null = 0,
        E_City = 1,
        E_Res = 2,
        E_CityAndRes = 3,// 主城或者资源点
        E_Alliance = 4,// 联盟街区点
        E_Wonder = 5,// 奇观
        E_Checkpoint = 6,// 关卡
        E_RallyPoint = 7,//  联盟中立资源点
        E_RaderRpg = 8,// 雷达RPG功能建筑
        E_RaderRts = 9,// 雷达RTS功能建筑
        E_WonderPoint_1 = 10, // 奇观功能点 建筑
        E_WonderPoint_2 = 11, // 奇观功能点 增援队
        E_WonderPoint_3 = 12, // 奇观功能点 突击队
        E_StationPoint = 20,// 关卡通行点

        E_ActivityBuild = 21,// 活动建筑出生点


        E_EditorResPoint = 100,// 编辑用资源点 -不会导出给服务器 只是客户端用来编辑的资源点
    }

    public static List<int> MapShowAdornPointType = new List<int> {1,2,7,21,100 };

    public static Dictionary<int,bool> showMapType = new Dictionary<int, bool>();

    public static bool GetShowMapType(int type)
    {
        bool bShow = false;
        showMapType.TryGetValue(type, out bShow);
        return bShow;
    }

    public static Dictionary<int, bool> allianceChuncks = new Dictionary<int, bool>();
    public void SetAllianceChunck(int tileIndex,bool value)
    {
        allianceChuncks[tileIndex] = value;
    }
    public static bool GetAllianceChunck(int tileIndex)
    {
        bool bShow = false;
        if (allianceChuncks.ContainsKey(tileIndex))
        {
            bShow = allianceChuncks[tileIndex];
        }
        return bShow;
    }

    /// <summary>
    /// 设置沙盘的出生点 占领检查 -ture 只显示已被占领的联盟领地的出生点
    /// </summary>
    /// <returns></returns>
    public void SetMapPointCheck(bool enabled)
    {
        bMapPointCheck = enabled;
    }

    public static bool GetMapPointCheck()
    {
       return bMapPointCheck;
    }

    /// <summary>
    /// 显示沙盒主城出生点
    /// </summary>
    public void ShowMapPoint(bool enabled)
    {
        bMapPointShow = enabled;
        if (enabled)
        {
            showMapType[(int)MapPointType.E_CityAndRes] = true;
            showMapType[(int)MapPointType.E_City] = true;
        }
        else
        {
            showMapType[(int)MapPointType.E_CityAndRes] = false;
            showMapType[(int)MapPointType.E_City] = false;
        }
        // 为当前所有的地图块创建显示出生点命令
        LODTileLayerListener layerListener = TileDisplayManager.Instance.GetTileLayerListener(MAP_POINT_ID);
        if (layerListener != null)
        {
            if (bMapPointShow)
            {
                layerListener.OnAddMapAllPoint();
            }
            else
            {
                layerListener.OnRemoveMapAllPoint();
            }
        }
    }

    public void ShowAllianceBuildPoint(bool enabled)
    {
        bMapPointShow = enabled;
        if (enabled)
        {
            showMapType[(int)MapPointType.E_Alliance] = true;
        }
        else
        {
            showMapType[(int)MapPointType.E_Alliance] = false;
        }
        // 为当前所有的地图块创建显示出生点命令
        LODTileLayerListener layerListener = TileDisplayManager.Instance.GetTileLayerListener(MAP_POINT_ID);
        if (layerListener != null)
        {
            if (bMapPointShow)
            {
                layerListener.OnAddMapAllPoint();
            }
            else
            {
                layerListener.OnRemoveMapAllPoint();
            }
        }
    }

    public bool GetMapPointInView()
    {
        bool inView = false;
        LODTileLayerListener layerListener = TileDisplayManager.Instance.GetTileLayerListener(MAP_POINT_ID);
        if (layerListener != null)
        {
            inView = layerListener.IsMapPointRender();
        }
        return inView;
    }

    public bool CheckTerrainCollider(Vector3 pos,float r,int layerMask)
    {
        bool res = true;
        res = !Physics.CheckSphere(pos, r, layerMask);
        return res;
    }

    /// <summary>
    /// 设置摄像机的格子尺寸
    /// </summary>
    /// <param name="width">格子宽度（米）</param>
    /// <param name="height">格子高度（米）</param>
    public void SetCameraGridSize(int width, int height)
    {
        m_CameraLayerContainerStrategy.SetGridSize(width, height);
    }

    /// <summary>
    /// 添加摄像机的LOD格子范围
    /// </summary>
    /// <param name="lodLevel"></param>
    /// <param name="gridRow"></param>
    /// <param name="gridCol"></param>
    public void AddCameraLODGridRange(int lodLevel, int gridRow, int gridCol)
    {
        m_CameraLayerContainerStrategy.AddLODGridRange(lodLevel, gridRow, gridCol);
    }

    /// <summary>
    /// 添加地图数据
    /// </summary>
    /// <param name="worldMapData"></param>
    public void AddWorldMapData(WorldMapData worldMapData)
    {
        //var mapLayers = worldMapData.mapLayers;
        var mapLayerRunDatas = worldMapData.mapLayerRunDtas;
        // 遍历所有层级
        for (int i = 0, cnt1 = mapLayerRunDatas.Count; i < cnt1; i++)
        {
            var mapLayerRunData = mapLayerRunDatas[i];
            TileDisplayManager.Instance.AddLayerContainer(mapLayerRunData.layerID, m_CameraLayerContainerStrategy);
         
            // 层级管理器 管理当前Layer的所有LOD的 控制层级的开关
            var lodLayerContainer = GetLODLayerContainer(mapLayerRunData.name);  
            lodLayerContainer.SetStrategy(m_CameraLayerContainerStrategy);
            // LOD缩放数据管理
            var lodStrategy = GetLodStrategy();
            // 层级对象管理生成
            var lodTileLayerListener = GetTileLayerListener(mapLayerRunData.name, mapLayerRunData.layerID, m_DisplayCommandManager);
            // 添加层级的所有LOD等级
            var displayLods = mapLayerRunData.displayLods;
            for (int j = 0, cnt2 = displayLods.Count; j < cnt2; j++)
            {
                var displayLodData = displayLods[j];
                int lod = displayLodData.x;
                int tileSize = displayLodData.y;
                //lodStrategy.AddCameraHeightByLod(lod); // 添加该LOD策略的判断高度

                // 对该层级添加不同的LOD等级
                // 这里默认将mapLODDatas的序号作为了lod等级。LODTileLayer的LayerID也赋值为LOD等级便于后续参数传递。地图左下角的世界坐标也默认设为了(0, 0)
                int min_size = -60; // 暂时使用-60
                LODTileLayer lodTileLayer = new LODTileLayer(tileSize, new int4 { x = min_size , y = min_size, z = m_seaSize, w = m_seaSize });
                lodLayerContainer.AddLayer(mapLayerRunData.layerID, lod, lodTileLayer);
                TileDisplayManager.Instance.AddTileLayer(mapLayerRunData.layerID, lod, lodTileLayer);
                lodTileLayer.SetScaleStrategy(GetLODScaleStrategy(mapLayerRunData.name));
            }
            lodStrategy.AddLODListener(lodLayerContainer); // 让层级监听这个LOD策略
            TileDisplayManager.Instance.AddLodStrategy(mapLayerRunData.layerID,lodStrategy);
            TileDisplayManager.Instance.AddTileLayerListener(mapLayerRunData.layerID, lodTileLayerListener);
            m_LayerContainerMananger.AddLayerContainer(lodLayerContainer, mapLayerRunData.layerID);
            m_LODManager.AddLODStrategy(lodStrategy);
        }
    }

    private LODLayerContainer GetLODLayerContainer(string layerName)
    {
        return new LODLayerContainer();
    }

    /// <summary>
    /// 获取指定层缩放策略
    /// </summary>
    /// <param name="layerName">层名称</param>
    /// <returns>缩放策略</returns>
    private ILODScaleStrategy GetLODScaleStrategy(string layerName)
    {
        ILODScaleStrategy lodScaleStrategy = null;

        return lodScaleStrategy;
    }

    /// <summary>
    /// 获取LOD缩放监听器和地块层级监听器
    /// </summary>
    /// <param name="layerName">层名称</param>
    /// <returns>监听对像</returns>
    private LODTileLayerListener GetTileLayerListener(string layerName, int layerID, IDisplayCommandInterface displayCommandInterface)
    {
        LODTileLayerListener tileLayerListener = null;
        switch (layerName)
        {
            default:
                tileLayerListener = new LODTileLayerListener(layerID, displayCommandInterface);
                break;
        }

        return tileLayerListener;
    }

    public CameraHeightLODStrategy GetLodStrategy()
    {
        var lodStrategy = new CameraHeightLODStrategy(m_Camera);
        lodStrategy.AddCameraHeight(DISTANCE_LOD0);
        lodStrategy.AddCameraHeight(DISTANCE_LOD1);
        lodStrategy.AddCameraHeight(DISTANCE_LOD2);
        lodStrategy.AddCameraHeight(DISTANCE_LOD3);
        lodStrategy.AddCameraHeight(DISTANCE_LOD4);
        lodStrategy.AddCameraHeight(DISTANCE_LOD5);
        return lodStrategy;
    }

    /// <summary>
    /// 添加自定义LOD层级，可以指定每个LOD等级的高度，指定了多少个高度即为多少个LOD等级
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="lodLayer">LOD层级</param>
    /// <param name="heights">LOD等级对应的高度区间</param>
    [DoNotGen]
    public void AddCustomLODLayer<T>(T lodLayer, params int[] heights) where T : Layer, ILODListener
    {
        // 创建LOD策略
        var lodStrategy = new CameraHeightLODStrategy(m_Camera);
        foreach (var height in heights)
        {
            lodStrategy.AddCameraHeight(height);
        }
        m_LODManager.AddLODStrategy(lodStrategy);

        AddCustomLODLayer(lodLayer, lodStrategy);
    }

    /// <summary>
    /// 添加自定义LOD层级。使用了默认的LOD高度策略。详见DISTANCE_LOD0到DISTANCE_LOD5的变量定义
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="lodLayer">LOD层级</param>
    [DoNotGen]
    public void AddCustomLODLayer<T>(T lodLayer) where T : Layer, ILODListener
    {
        AddCustomLODLayer(lodLayer, m_DefaultCameraHeightLODStrategy);
    }


    /// <summary>
    /// 添加自定义LOD层级容器.使用了默认的LOD高度策略。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="lodLayerContainer">支持LOD的层级容器</param>
    /// <returns>返回容器的ID</returns>
    [DoNotGen]
    public void AddCustomLODContainer<T>(T lodLayerContainer) where T : LayerContainer, ILODListener
    {
        // 创建LOD策略
        m_DefaultCameraHeightLODStrategy.AddLODListener(lodLayerContainer);

        // 创建层级容器
        lodLayerContainer.SetStrategy(m_CameraLayerContainerStrategy);
        m_LayerContainerMananger.AddLayerContainer(lodLayerContainer);
    }

    /// <summary>
    /// 移除自定义LOD层级容器
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="lodLayerContainer">支持LOD的层级容器</param>
    [DoNotGen]
    public void RemoveCustomLODContainer<T>(T lodLayerContainer) where T : LayerContainer, ILODListener
    {
        m_DefaultCameraHeightLODStrategy.RemoveLODImplement(lodLayerContainer);
        m_LayerContainerMananger.RemoveContainer(lodLayerContainer);
    }

    public void AddTileTraffic(int tileIdx,int lod)
    {
        if (lod != (int)LODLevelEnum.LOD1) return;
        if (_trafficSystem) _trafficSystem.CreateChunckTraffic(tileIdx);
    }

    public void RemoveTileTraffic(int tileIdx, int lod)
    {
        if (lod != (int)LODLevelEnum.LOD1) return;
        if (_trafficSystem) _trafficSystem.RemoveChunckTraffic(tileIdx);
    }

    public void SetCarNum(int carNum)
    {
        if (_trafficSystem)
        {
            _trafficSystem.setCarNum(carNum);
        }
    }

    public void SetCarCheck(bool isCarCheck)
    {
        if (_trafficSystem)
        {
            _trafficSystem.setCarCheck(isCarCheck);
        }
    }

    public void SetTrafficEnabled(bool isEnabled)
    {
        if (_trafficSystem)
        {
            _trafficSystem.isOn = isEnabled;
        }
    }

    public void SetTrafficOpen(bool isEnabled)
    {
        if (_trafficSystem)
        {
            _trafficSystem.setCarEnable(isEnabled);
        }
    }

    /// <summary>
    /// 创建
    /// </summary>
    public void Create()
    {
        m_LayerContainerMananger = new LayerContainerManager();
        m_LODManager = new LODManager();
        m_DisplayCommandManager = new DisplayCommandManager();
        m_DisplayCommandManager.SetFactory(new WorldObjectDisplayElementFactory());
        m_CameraLayerContainerStrategy = new GridLodCameraLayerContainerStrategy(m_Camera);
        _worldAudioController = new WorldAudioController(m_Camera);

        // 默认的LOD策略
        m_DefaultCameraHeightLODStrategy = new CameraHeightLODStrategy(m_Camera);
        m_DefaultCameraHeightLODStrategy.AddCameraHeight(DISTANCE_LOD0);
        m_DefaultCameraHeightLODStrategy.AddCameraHeight(DISTANCE_LOD1);
        m_DefaultCameraHeightLODStrategy.AddCameraHeight(DISTANCE_LOD2);
        m_DefaultCameraHeightLODStrategy.AddCameraHeight(DISTANCE_LOD3);
        m_DefaultCameraHeightLODStrategy.AddCameraHeight(DISTANCE_LOD4);
        m_DefaultCameraHeightLODStrategy.AddCameraHeight(DISTANCE_LOD5);
        m_LODManager.AddLODStrategy(m_DefaultCameraHeightLODStrategy);

        m_TreeLayerCollisionData = new CircleSimpleBoolCollisionData(GlobalValue.TREE_LAYER_COLLISION_GRID_SIZE);

        m_DefaultCameraHeightLODStrategy.AddLODListener(m_CameraLayerContainerStrategy);
        // GameObject trafficSystemObj = new GameObject();
        //_trafficSystem = trafficSystemObj.AddComponent<TrafficSystem>();
        //_trafficSystem.Init();
        // 街区点 车道
        GameObject alliancePointObj = new GameObject("alliancePointSystem");
        _alliancePointSystem = alliancePointObj.AddComponent<MapAlliancePointSystem>();
        _alliancePointSystem.Init(m_DisplayCommandManager);
        // 出生点 装饰物
        GameObject mapPointAdornObj = new GameObject("mapPointAdornSystem");
        _mapPointAdornSystem = mapPointAdornObj.AddComponent<MapPointAdornSystem>();
        _mapPointAdornSystem.Init(m_DisplayCommandManager);
        
        AddCustomLODLayer(_worldGlobalLodListener);
    }

    /// <summary>
    /// 销毁
    /// </summary>
    public void Destroy()
    {
        instance = null;
        m_LayerContainerMananger.Clear();
        m_LODManager.Clear();
        m_DisplayCommandManager.Clear();
        m_TreeLayerCollisionData.Clear();
        m_DefaultCameraHeightLODStrategy.Destroy();
        TileDisplayManager.Instance.Clear();
        _worldAudioController.Clear();

        m_LayerContainerMananger = null;
        m_LODManager = null;
        m_DisplayCommandManager = null;
        m_TreeLayerCollisionData = null;
        m_DefaultCameraHeightLODStrategy = null;
        m_CameraLayerContainerStrategy = null;
        DynamicLayerMgr.worldEntry = null;
        _worldAudioController = null;
        if (_trafficSystem)
        {
            _trafficSystem.DisPose();
            GameObject.Destroy(_trafficSystem.gameObject);
        }

        ClassManager.GetInstance().Clear<MultiElementTile>();
        ClassManager.GetInstance().Clear<DisplayCmdHashContainer>();

#if UNITY_EDITOR
        _touchCameraController.onValidate -= OnCameraValidate;
#endif
        SpriteAtlasFrame.Instance.disposeRes();

        if (_alliancePointSystem)
        {
            _alliancePointSystem.DisPose();
        }
        _alliancePointSystem = null;

        if (_mapPointAdornSystem)
        {
            _mapPointAdornSystem.DisPose(false);
        }
        _mapPointAdornSystem = null;
    }

    private void OnCameraValidate()
    {
        if (_touchCameraController)
        {
            WorldEntry.DISTANCE_LOD0 = _touchCameraController.LOD1;
            WorldEntry.DISTANCE_LOD1 = _touchCameraController.LOD2;
            WorldEntry.DISTANCE_LOD2 = _touchCameraController.LOD3;
            WorldEntry.DISTANCE_LOD3 = _touchCameraController.LOD4;
            WorldEntry.DISTANCE_LOD4 = _touchCameraController.LOD5;
            WorldEntry.DISTANCE_LOD5 = _touchCameraController.ZoomDistanceMax;
        }
    }

    private bool debug = false;

    /// <summary>
    /// 轮询更新
    /// </summary>
    public void Update()
    {
        WorldCameraManager.GetInstance().OnUpdate();
        if (!UpdateSwitch)
        {
            return;
        }

        UnityEngine.Profiling.Profiler.BeginSample("WorldMap Update");
        UnityEngine.Profiling.Profiler.BeginSample("TileDisplayManager Update");
        TileDisplayManager.Instance.OnUpdate();
        UnityEngine.Profiling.Profiler.EndSample();
        
        UnityEngine.Profiling.Profiler.BeginSample("LodMananger Update");
        m_LODManager.Update();
        UnityEngine.Profiling.Profiler.EndSample();

        UnityEngine.Profiling.Profiler.BeginSample("LayerContainerMananger Update");
        m_LayerContainerMananger.Update();
        UnityEngine.Profiling.Profiler.EndSample();

        UnityEngine.Profiling.Profiler.BeginSample("DisplayCommandManager Update");
        m_DisplayCommandManager.Update();
        UnityEngine.Profiling.Profiler.EndSample();

        UnityEngine.Profiling.Profiler.BeginSample("TrafficSystem Update");
        if (_trafficSystem) _trafficSystem.OnUpdate();
        UnityEngine.Profiling.Profiler.EndSample();
        UnityEngine.Profiling.Profiler.EndSample();
    }


    private void AddCustomLODLayer<T>(T lodLayer, LODStrategy lodStrategy) where T : Layer, ILODListener
    {
        // 创建层级容器
        var layerContainer = new LayerContainer();
        layerContainer.SetStrategy(m_CameraLayerContainerStrategy);
        layerContainer.AddLayer(0,0, lodLayer, true);
        m_LayerContainerMananger.AddLayerContainer(layerContainer);

        // 创建LOD策略
        lodStrategy.AddLODListener(lodLayer);
    }

    public int GetLODLevel()
    {
        return m_DefaultCameraHeightLODStrategy.GetLastLODLevel();
    }

    public float GetLODPercent()
    {
        return m_DefaultCameraHeightLODStrategy.GetLastLODPercent();
    }

    public LayerContainer GetLayerContainer(int layerId)
    {
        return m_LayerContainerMananger.GetLodContainer(layerId);
    }

    public int GetLightState(int tileIdx, int nodeId, int sideId1, int sideId2)
    {
        int state = 0;
        if (_trafficSystem)
        {
            state = _trafficSystem.GetLightState(tileIdx,nodeId,sideId1,sideId2);
        }
        return state;
    }
    
    public void ResetSandboxDecorationQuality(int level)
    {
        WorldMapConfigData.SetMapChunckLevel(level);
        LODTileLayerListener layerListener = TileDisplayManager.Instance.GetTileLayerListener(TREE_LAYER_ID);
        if (layerListener != null)
        {
            layerListener.ResetQuality();
        }
    }

    public Camera GetCamera()
    {
        return m_Camera?.GetCamera();
    }

    #region 背景音乐部分
    /// <summary>
    /// 播放正常的背景音乐
    /// </summary>
    public void PlayNormalBackMusic()
    {
        _worldAudioController?.PlaySandBackMusic(BackMusicType.NORMAL_STATE);
    }

    /// <summary>
    /// 播放战斗时背景音乐
    /// </summary>
    public void PlayBattleBackMusic()
    {
        _worldAudioController?.PlaySandBackMusic(BackMusicType.BATTLE_STATE);
    }
    #endregion

    // 获得lod对应layer 尺寸 用于lod粒度修改 
    //假如一个地图块大小固定(美术编辑大小) 但是运行的时候又不想一下加载整个地图块上所有对象 就可以使用粒度拆分
    public static int GetLayerSizeByLod(int layerId, int lod)
    {
        if (layerId == WorldEntry.TREE_LAYER_ID && lod == 1)
        {
            return 10;
        }
        return WorldEntry.m_iTileSize;
    }
}
